Centralt innehåll
- Arv, inkapsling och polymorfism.
1. Arv
Om en klass definieras utifrån en annan klass kallas det arv. Det innebär att man skapar en ny klass (subklass) utifrån en redan existerande klass, som kallas basklass eller superklass. Subklassen ärver basklassens egenskaper och beteenden, dvs attribut och metoder.
Subklassen Penguin ärver metoden sound()
och definierade en ny metod run()
.
# Base class
class Bird:
def __init__(self):
print("Bird is created")
def sound(self):
print("Peep")
# Sub class
class Penguin(Bird): # Inherits from Bird
def __init__(self):
super().__init__() # Calls the super class constructor
print("Penguin is created")
def run(self):
print("Run")
peggy = Penguin()
peggy.sound()
peggy.run()
ger utskriften
Bird is created
Penguin is created
Peep
Run
I detta exempel används print
i metoderna endast för att åskådliggöra hur arv fungerar.
Kom ihåg att användning av print
i klassens metoder inte är bra design.
Subklassen Rectangle ärver attributen x
och y
och definerar nya metoderna area()
och perimeter()
.
# Base class
class Shape:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return f'The shapes coordinate: ({self.x}, {self.y})'
# Sub class
class Rectangle(Shape): # Inherits from Shape
def __init__(self, x, y, width, height):
super().__init__(x, y) # Calls the super class constructor
self.width = width
self.height = height
def area(self):
return self.width * self.height
def perimeter(self):
return 2 * self.width + 2 * self.height
rect = Rectangle(0, 0, 3, 4)
print(rect)
print(f'Rectangle area: {rect.area()}')
print(f'Rectangle perimeter: {rect.perimeter()}')
ger utskriften
The shapes coordinate: (0, 0)
Rectangle area: 12
Rectangle perimeter: 14
Arv bidrar till att kunna återanvända kod (klasser) eftersom vi kan använda en befintlig klass och dess egenskaper
istället för att skapa en klass från början med samma egenskaper.
Om det finns en klass med ett antal egenskaper och metoder och man behöver en klass som är nästan likadan,
men att den ska ha ytterligare attribut och/eller metoder, då är det bra att använda arv.
Ett bra sätt för att avgöra om ett arv är lämpligt eller inte är att sätta samman påståendet:
"Subklassen är en/ett basklass", t.ex. "Pingvin är en Fågel" och "Rektangel är en Figur".
Viktigt alltså med bra beskrivande klassnamn, som enligt praxis är substantiv, singularis och har stor första bokstav.
- Arv gör att en klass kan definieras baserat på en annan klass.
- Arv är ett sätt att skapa en ny klass och att återanvända detaljer i en befintlig klass utan att ändra den.
- Den klass som man ärver ifrån kallas basklass eller superklass.
- Klassen som ärver egenskaper och beteenden (attribut och metoder) kallas subklass.
2. Override
Vi har sett att om det finns en klass med egenskaper och beteenden (attribut och metoder) kan en ny klass skapas som ärver
alla attribut och metoder och kan även lägga till fler attribut och metoder.
Dessutom kan befintliga metoder i basklassen definieras om i subklassen. Det kallas för override (överskuggning på svenska).
Det görs genom att i subklassen definiera en metod med samma namn som en metod i basklassen.
Subklassen Penguin definierar om metoden who_are_you()
som också finns i basklassen.
# Base class
class Bird:
def __init__(self):
print("Bird is created")
def sound(self):
print("Peep")
def who_are_you(self):
print("I'm a Bird")
# Sub class
class Penguin(Bird): # Inherits from Bird
def __init__(self):
super().__init__() # Calls the super class constructor
print("Penguin is created")
def run(self):
print("Run")
def who_are_you(self):
print("I'm a Penguin")
peggy = Penguin()
peggy.sound()
peggy.run()
peggy.who_are_you()
ger utskriften
Bird is created
Penguin is created
Peep
Run
I'm a Penguin
Subklassen Penguin ärver metoderna i basklassen Bird. Det syns när metoden sound()
anropas. Subklassen har ingen sådan metod,
så därför anropas basklassens sound()
metod.
Subklassen Penguin gör override på metoden
who_are_you()
, som alltså också definieras i basklassen Bird.
Subklassen Rectangle gör override på metoden __str__()
, som också finns i basklassen Shape.
# Base class
class Shape:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return f'The shapes coordinates: ({self.x}, {self.y})'
# Sub class
class Rectangle(Shape): # Inherits from Shape
def __init__(self, x, y, width, height):
super().__init__(x, y) # Calls the super class constructor
self.width = width
self.height = height
def __str__(self):
return f'The rectangles coordinate: ({self.x}, {self.y})'
def area(self):
return self.width * self.height
def perimeter(self):
return 2 * self.width + 2 * self.height
rect = Rectangle(0, 0, 3, 4)
print(rect)
print(f'Rectangle area: {rect.area()}')
print(f'Rectangle perimeter: {rect.perimeter()}')
ger utskriften
The rectangles coordinate: (0, 0)
Rectangle area: 12
Rectangle perimeter: 14
- Arv är ett sätt att återanvända kod från redan existerande klasser.
- En subklass ärver egenskaper och beteenden (attribut och metoder) från basklassen.
- En subklass kan lägga till nya attribut och metoder.
- Det kallas för override när en subklass definierar om basklassens metoder.
Begrepp
Attribut: Variabler i en klass.
Metod: En funktion kopplad till ett objekt.
Inkapsling: Att skydda attribut i ett objekt för okontrollerad ändringar.
Arv: När klasser definieras baserat på en annan klass.
Subklass: Klassen som ärver egenskaper och beteenden (attribut och metoder).
Basklass: Den klass som man ärver ifrån.
Superklass: Samma som basklass.
Override: Omdefinerar en metod i basklassen.
Film
Fakta
Övningar
1. En klasshierarki beskriver vilken klass som ärver från vilken.
Skapa en klasshierarki av följande:
Lastbil, Cykel, Moped, Bil, Fordon
2. Skapa en klasshierarki av följande:
Djur, Kyckling, Hund, Katt, Fågel, Schäfer, Däggdjur, Sparv, Pudel
3. Du ska skriva en klass Person.
Klassen Person har tre attribut: first_name
, last_name
och birth_year
.
Konstruktorn ska ha parametrar för alla tre attribut.
Metoden age(self, current_year)
, har aktuellt årtal som parameter och returnerar personens ålder.
Metoden __str__()
, ska returnera information (namn och födelseår) om personen (se exempel-utskrift nedan).
Kom ihåg att klasserna inte får innehålla print
-satser.
Programmet som ska köras är:
person = Person("Jan", "Gran", 1986)
print(person)
print(f'{person.first_name} är {person.age(2022)} år')
och ska då ge utskriften
Jan Gran är född 1986
Jan är 36 år
4. Du ska skriva en klass Teacher, som ärver från klassen Person.
Subklassen Teacher har attributen salary
(månadslönen) och employed_year
(anställningsår).
Konstruktorn ska ha parametrar för first_name
, last_name
, birth_year
, salary
och employed_year
.
Metoden __str__()
, som returnerar information (namn, födelseår och månadslön) om läraren (se exempel-utskrift nedan).
Metoden get_years_of_employment(current_year)
, som returnerar ett * för varje år läraren varit anställd (se exempel-utskrift nedan).
Kom ihåg att klasserna inte får innehålla print
-satser.
Programmet som ska köras är:
teacher = Teacher("Jan", "Gran", 1986, 28000, 2015)
print(teacher)
print(f'Läraren {teacher.first_name} är {teacher.age(2022)} år')
print(f'Antal anställningsår: {teacher.get_years_of_employment(2022)}')
och ska då ge utskriften
Jan Gran är född 1986 och tjänar 28000 kr/månad
Läraren Jan är 36 år
Antal anställningsår: *******